package com.ruoyi.training.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.training.dto.payment.FundPoolCorrelationInfo;
import com.ruoyi.training.dto.registration.RegistrationDto;
import com.ruoyi.training.mapper.RegistrationMapper;
import com.ruoyi.training.util.xuehua.SnowflakeIdUtils;
import com.ruoyi.training.vo.payment.FundPoolVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.training.mapper.FundPoolMapper;
import com.ruoyi.training.domain.FundPool;
import com.ruoyi.training.service.IFundPoolService;

/**
 * 资金池Service业务层处理
 *
 * @author hcc
 * @date 2025-09-28
 */
@Service
public class FundPoolServiceImpl implements IFundPoolService
{
    @Autowired
    private FundPoolMapper fundPoolMapper;

    @Autowired
    private RegistrationMapper registrationMapper;
    /**
     * 查询资金池
     *
     * @param fundPoolId 资金池主键
     * @return 资金池
     */
    @Override
    public FundPool selectFundPoolByFundPoolId(String fundPoolId)
    {
        return fundPoolMapper.selectFundPoolByFundPoolId(fundPoolId);
    }

    /**
     * 查询资金池列表
     *
     * @param fundPool 资金池
     * @return 资金池
     */
    @Override
    public List<FundPool> selectFundPoolList(FundPool fundPool)
    {
        return fundPoolMapper.selectFundPoolList(fundPool);
    }

    /**
     * 新增资金池
     *
     * @param fundPool 资金池
     * @return 结果
     */
    @Override
    public int insertFundPool(FundPool fundPool)
    {
        fundPool.setFundPoolId(String.valueOf(new SnowflakeIdUtils(5,8).nextId()));
        fundPool.setCreateTime(DateUtils.getNowDate());
        fundPool.setPoolDelFlag("0");
        return fundPoolMapper.insertFundPool(fundPool);
    }

    /**
     * 修改资金池
     *
     * @param fundPool 资金池
     * @return 结果
     */
    @Override
    public int updateFundPool(FundPool fundPool)
    {
        fundPool.setUpdateTime(DateUtils.getNowDate());
        return fundPoolMapper.updateFundPool(fundPool);
    }

    /**
     * 批量删除资金池
     *
     * @param fundPoolIds 需要删除的资金池主键
     * @return 结果
     */
    @Override
    public int deleteFundPoolByFundPoolIds(String[] fundPoolIds)
    {
        return fundPoolMapper.deleteFundPoolByFundPoolIds(fundPoolIds);
    }

    /**
     * 删除资金池信息
     *
     * @param fundPoolId 资金池主键
     * @return 结果
     */
    @Override
    public int deleteFundPoolByFundPoolId(String fundPoolId)
    {
        return fundPoolMapper.deleteFundPoolByFundPoolId(fundPoolId);
    }
// TODO
    /**
     * 出账
     */
    @Override
    public int disbursement(FundPool fundPool) {
        String[] split = fundPool.getRegistrationId().split(",");
        BigDecimal totalCost = BigDecimal.ZERO;
        StringBuffer information = new StringBuffer();
        // 处理学员姓名拼接：最后一个不追加分隔符
        for (int i = 0; i < split.length; i++) {
            String registrationId = split[i];
            RegistrationDto registrationDto = registrationMapper.selectRegistrationByRegistrationId(registrationId);
            if (registrationDto == null) {
                continue;
            }
            // 非第一个元素前加分隔符
            if (i > 0) {
                information.append(";");
            }
            information.append(registrationDto.getStudentName());
            // 累加项目费用
            if (StringUtils.isNotEmpty(registrationDto.getProjectSum())){
                BigDecimal projectSum = new BigDecimal(registrationDto.getProjectSum());
                totalCost = totalCost.add(projectSum);
            }else {
                BigDecimal projectSum = BigDecimal.ZERO;
                totalCost = totalCost.add(projectSum);
            }
        }
        fundPool.setPoolOutInformation(information.toString());
        fundPool.setPoolOutAmount(totalCost.stripTrailingZeros().toPlainString());
        FundPool fundPoolDb = fundPoolMapper.selectFundPoolByFundPoolId(fundPool.getFundPoolId());
        // 计算余额
        BigDecimal poolInAmount = new BigDecimal(fundPoolDb.getPoolInAmount());
        BigDecimal balance = poolInAmount.subtract(totalCost);
        // 处理余额格式：去除末尾0，避免科学计数法
        String balanceStr = balance.stripTrailingZeros().toPlainString();
        fundPool.setPoolBalance(balanceStr);
        fundPool.setPoolOutTime(DateUtils.getNowDate());
        fundPool.setUpdateTime(DateUtils.getNowDate());
        return fundPoolMapper.updateFundPool(fundPool);
    }
    // TODO
    /**
     * 出账并合并发票
     */
    @Override
    public int consolidateInvoice(FundPool fundPool) {
        disbursement(fundPool);
        return 0;
    }

    /**
     * 逻辑删除资金池
     */
    @Override
    public int removeFundPool(String[] fundPoolIds) {
        return fundPoolMapper.removeFundPool(fundPoolIds);
    }

    /**
     * 查询资金池列表
     */
    @Override
    public List<FundPool> selectList(FundPoolVo fundPoolVo) {
        return fundPoolMapper.selectList(fundPoolVo);
    }

    // 通过交易号查询资金池
    @Override
    public FundPool selectFundPoolByPoolTransactionNum(String poolTransactionNum) {
        return fundPoolMapper.selectFundPoolByPoolTransactionNum(poolTransactionNum);
    }

    /**
     * 获取资金池关联报名信息
     */
    @Override
    public FundPoolCorrelationInfo getFundPoolCorrelationInfo(String fundPoolId) {
        FundPoolCorrelationInfo fundPoolCorrelationInfo = new FundPoolCorrelationInfo();
        if (StringUtils.isNotEmpty(fundPoolId)) {
            FundPool fundPool = fundPoolMapper.selectFundPoolByFundPoolId(fundPoolId);
            if (StringUtils.isNotNull(fundPool)){
                BeanUtils.copyProperties(fundPool,fundPoolCorrelationInfo);
                if (StringUtils.isNotEmpty(fundPool.getRegistrationId())){
                    List<RegistrationDto> registrationDtoList = new ArrayList<>();
                    String[] split = fundPool.getRegistrationId().split(",");
                    for (String registrationId : split) {
                        RegistrationDto registrationDto = registrationMapper.selectRegistrationByRegistrationId(registrationId);
                        registrationDtoList.add(registrationDto);
                    }
                    fundPoolCorrelationInfo.setRegistrationDtoList(registrationDtoList);
                }
            }
        }
        return fundPoolCorrelationInfo;
    }
}
